import { Injectable, Logger } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { ConfigService } from '../config/config.service';
import {
  AnalysisRequest,
  AnalysisResponse,
  TradingRecommendation,
  ConsensusDecision,
  TradingRole,
  RolePrompt,
} from './interfaces/deepseek.interface';
import { firstValueFrom } from 'rxjs';

@Injectable()
export class DeepSeekService {
  private readonly logger = new Logger(DeepSeekService.name);
  private readonly rolePrompts: Map<TradingRole, RolePrompt> = new Map();

  constructor(
    private httpService: HttpService,
    private configService: ConfigService,
  ) {
    this.initializeRolePrompts();
  }

  private initializeRolePrompts() {
    // 技术分析师角色
    this.rolePrompts.set(TradingRole.TECHNICAL_ANALYST, {
      role: TradingRole.TECHNICAL_ANALYST,
      systemPrompt: `你是一名专业的技术分析师，专门分析加密货币市场的技术指标和价格走势。
你的职责是：
1. 分析K线图形态、支撑阻力位
2. 计算和解读技术指标（RSI、MACD、布林带等）
3. 识别趋势方向和反转信号
4. 提供基于技术分析的交易建议
请始终保持客观和专业，基于数据做出分析。`,
      analysisPrompt: `请基于以下市场数据进行技术分析：
市场数据：{marketData}
K线数据：{klineData}
当前持仓：{positions}

请分析：
1. 当前趋势方向
2. 关键支撑阻力位
3. 技术指标信号
4. 入场/出场时机
5. 风险收益比

请以JSON格式返回分析结果，包含：action（BUY/SELL/HOLD/CLOSE）、confidence（0-100）、reasoning、urgency（LOW/MEDIUM/HIGH/CRITICAL）。`,
    });

    // 基本面分析师角色
    this.rolePrompts.set(TradingRole.FUNDAMENTAL_ANALYST, {
      role: TradingRole.FUNDAMENTAL_ANALYST,
      systemPrompt: `你是一名专业的基本面分析师，专门分析影响加密货币价格的宏观经济和基本面因素。
你的职责是：
1. 分析宏观经济环境对加密货币的影响
2. 评估项目基本面和发展前景
3. 关注市场情绪和资金流向
4. 提供基于基本面的中长期投资建议
请保持理性和前瞻性的分析视角。`,
      analysisPrompt: `请基于以下信息进行基本面分析：
市场数据：{marketData}
账户信息：{accountInfo}
当前持仓：{positions}

请分析：
1. 当前市场环境和情绪
2. 宏观经济因素影响
3. 资金流向和成交量分析
4. 中长期趋势判断
5. 基本面支撑位

请以JSON格式返回分析结果，包含：action（BUY/SELL/HOLD/CLOSE）、confidence（0-100）、reasoning、urgency（LOW/MEDIUM/HIGH/CRITICAL）。`,
    });

    // 风险管理师角色
    this.rolePrompts.set(TradingRole.RISK_MANAGER, {
      role: TradingRole.RISK_MANAGER,
      systemPrompt: `你是一名专业的风险管理师，负责评估和控制交易风险。
你的职责是：
1. 评估当前持仓风险
2. 计算合理的仓位大小
3. 设定止损和止盈位
4. 监控账户风险指标
5. 提供风险控制建议
请始终将风险控制放在首位，确保资金安全。`,
      analysisPrompt: `请基于以下信息进行风险评估：
账户信息：{accountInfo}
当前持仓：{positions}
市场数据：{marketData}

请评估：
1. 当前账户风险水平
2. 持仓集中度风险
3. 杠杆使用情况
4. 建议的仓位大小
5. 止损止盈设置

请以JSON格式返回风险评估结果，包含：action（BUY/SELL/HOLD/CLOSE）、confidence（0-100）、reasoning、urgency（LOW/MEDIUM/HIGH/CRITICAL）、建议仓位大小、止损位、止盈位。`,
    });

    // 消息面分析师角色
    this.rolePrompts.set(TradingRole.NEWS_ANALYST, {
      role: TradingRole.NEWS_ANALYST,
      systemPrompt: `你是一名专业的消息面分析师，专门分析影响加密货币市场的新闻、事件和市场情绪。
你的职责是：
1. 分析重大新闻事件对市场的影响
2. 评估监管政策变化的市场影响
3. 监控社交媒体和市场情绪指标
4. 识别突发事件和黑天鹅风险
5. 提供基于消息面的短期交易建议
请保持敏锐的市场嗅觉，及时捕捉影响价格的关键信息。`,
      analysisPrompt: `请基于以下信息进行消息面分析：
市场数据：{marketData}
账户信息：{accountInfo}
当前持仓：{positions}

请分析：
1. 当前市场情绪和恐慌指数
2. 近期重大新闻事件影响
3. 监管政策变化风险
4. 社交媒体热度和舆论导向
5. 突发事件和市场异常信号
6. 机构资金流向和大户动向

请以JSON格式返回消息面分析结果，包含：action（BUY/SELL/HOLD/CLOSE）、confidence（0-100）、reasoning、urgency（LOW/MEDIUM/HIGH/CRITICAL）。`,
    });

    // 交易执行官角色
    this.rolePrompts.set(TradingRole.EXECUTION_OFFICER, {
      role: TradingRole.EXECUTION_OFFICER,
      systemPrompt: `你是一名专业的交易执行官，负责综合各方面分析并做出最终交易决策。
你的职责是：
1. 综合技术分析、基本面分析、风险管理和消息面分析的建议
2. 评估市场流动性和执行成本
3. 选择最佳的交易时机和方式
4. 制定具体的交易执行计划
5. 权衡各种分析结果的重要性和时效性
请保持冷静和理性，确保交易执行的最优化。`,
      analysisPrompt: `请基于以下综合信息制定交易执行计划：
技术分析建议：{technicalAnalysis}
基本面分析建议：{fundamentalAnalysis}
风险管理建议：{riskManagement}
消息面分析建议：{newsAnalysis}
当前市场状况：{marketData}
账户状况：{accountInfo}

请制定：
1. 最终交易决策
2. 具体执行方案
3. 时机选择
4. 订单类型选择
5. 执行优先级
6. 各分析权重评估
7. 交易数量计算（基于风险管理建议和账户余额）

请以JSON格式返回执行计划，必须包含以下字段：
- action（BUY/SELL/HOLD/CLOSE）
- confidence（0-100）
- reasoning（决策理由）
- urgency（LOW/MEDIUM/HIGH/CRITICAL）
- quantity（交易数量，数值类型，如果action为HOLD则为0）
- price（可选，限价单价格）
- stopLoss（可选，止损价格）
- takeProfit（可选，止盈价格）

注意：quantity字段必须是数值类型，基于账户可用余额和风险管理建议计算合理的交易数量。`,
    });
  }

  // 调用DeepSeek API（带重试机制）
  private async callDeepSeekAPI(prompt: string, systemPrompt: string): Promise<string> {
    const maxRetries = 3;
    const baseDelay = 2000; // 2秒基础延迟

    for (let attempt = 1; attempt <= maxRetries; attempt++) {
      try {
        this.logger.debug(`DeepSeek API 调用尝试 ${attempt}/${maxRetries}`);
        
        const response = await firstValueFrom(
          this.httpService.post(
            `${this.configService.deepseekBaseUrl}/chat/completions`,
            {
              model: 'deepseek-chat',
              messages: [
                {
                  role: 'system',
                  content: systemPrompt,
                },
                {
                  role: 'user',
                  content: prompt,
                },
              ],
              temperature: 0.7,
              max_tokens: 2000,
            },
            {
              headers: {
                'Authorization': `Bearer ${this.configService.deepseekApiKey}`,
                'Content-Type': 'application/json',
              },
              timeout: 60000, // 60秒超时
            },
          ),
        );

        this.logger.debug('DeepSeek API 调用成功');
        return response.data.choices[0].message.content;
        
      } catch (error) {
        const isLastAttempt = attempt === maxRetries;
        const isRetryableError = this.isRetryableError(error);
        
        this.logger.warn(
          `DeepSeek API 调用失败 (尝试 ${attempt}/${maxRetries}):`, 
          error.response?.data || error.message
        );

        if (isLastAttempt || !isRetryableError) {
          this.logger.error('DeepSeek API 最终调用失败:', {
            attempt,
            error: error.response?.data || error.message,
            isRetryableError,
          });
          throw error;
        }

        // 指数退避延迟
        const delay = baseDelay * Math.pow(2, attempt - 1);
        this.logger.debug(`等待 ${delay}ms 后重试...`);
        await new Promise(resolve => setTimeout(resolve, delay));
      }
    }
  }

  // 判断是否为可重试的错误
  private isRetryableError(error: any): boolean {
    // 网络连接错误
    if (error.code === 'ECONNRESET' || 
        error.code === 'ENOTFOUND' || 
        error.code === 'ETIMEDOUT' ||
        error.code === 'ECONNREFUSED') {
      return true;
    }

    // HTTP 状态码错误
    const status = error.response?.status;
    if (status) {
      // 5xx 服务器错误可重试
      if (status >= 500 && status < 600) {
        return true;
      }
      // 429 限流错误可重试
      if (status === 429) {
        return true;
      }
      // 408 请求超时可重试
      if (status === 408) {
        return true;
      }
    }

    return false;
  }

  // 单个角色分析
  async analyzeByRole(request: AnalysisRequest): Promise<AnalysisResponse> {
    const rolePrompt = this.rolePrompts.get(request.role);
    if (!rolePrompt) {
      const errorMsg = `未知的交易角色: ${request.role}`;
      this.logger.error(errorMsg);
      throw new Error(errorMsg);
    }

    const startTime = Date.now();
    this.logger.log(`🤖 ${request.role} 开始分析...`);

    try {
      // 构建分析提示词
      let analysisPrompt = rolePrompt.analysisPrompt
        .replace('{marketData}', JSON.stringify(request.marketData, null, 2))
        .replace('{accountInfo}', JSON.stringify(request.accountInfo, null, 2))
        .replace('{positions}', JSON.stringify(request.positions, null, 2))
        .replace('{klineData}', JSON.stringify(request.klineData.slice(-20), null, 2)); // 只取最近20根K线

      this.logger.debug(`${request.role} 提示词长度: ${analysisPrompt.length} 字符`);

      const aiResponse = await this.callDeepSeekAPI(analysisPrompt, rolePrompt.systemPrompt);
      
      if (!aiResponse || aiResponse.trim().length === 0) {
        throw new Error('DeepSeek API 返回空响应');
      }

      this.logger.debug(`${request.role} 收到响应，长度: ${aiResponse.length} 字符`);
      
      // 尝试解析JSON响应
      let parsedResponse: any;
      try {
        // 提取JSON部分
        const jsonMatch = aiResponse.match(/\{[\s\S]*\}/);
        if (jsonMatch) {
          parsedResponse = JSON.parse(jsonMatch[0]);
          this.logger.debug(`${request.role} JSON 解析成功`);
        } else {
          throw new Error('响应中未找到JSON格式');
        }
      } catch (parseError) {
        this.logger.warn(`${request.role} 响应解析失败，使用默认值:`, {
          error: parseError.message,
          responsePreview: aiResponse.substring(0, 200) + '...'
        });
        parsedResponse = {
          action: 'HOLD',
          confidence: 50,
          reasoning: aiResponse,
          urgency: 'LOW',
        };
      }

      // 验证解析结果
      const validActions = ['BUY', 'SELL', 'HOLD', 'CLOSE'];
      if (!validActions.includes(parsedResponse.action)) {
        this.logger.warn(`${request.role} 无效的 action: ${parsedResponse.action}，使用默认值 HOLD`);
        parsedResponse.action = 'HOLD';
      }

      const validUrgencies = ['LOW', 'MEDIUM', 'HIGH', 'CRITICAL'];
      if (!validUrgencies.includes(parsedResponse.urgency)) {
        this.logger.warn(`${request.role} 无效的 urgency: ${parsedResponse.urgency}，使用默认值 LOW`);
        parsedResponse.urgency = 'LOW';
      }

      if (typeof parsedResponse.confidence !== 'number' || parsedResponse.confidence < 0 || parsedResponse.confidence > 100) {
        this.logger.warn(`${request.role} 无效的 confidence: ${parsedResponse.confidence}，使用默认值 50`);
        parsedResponse.confidence = 50;
      }

      const recommendation: TradingRecommendation = {
        action: parsedResponse.action || 'HOLD',
        quantity: parsedResponse.quantity,
        price: parsedResponse.price,
        stopLoss: parsedResponse.stopLoss,
        takeProfit: parsedResponse.takeProfit,
        leverage: parsedResponse.leverage,
        urgency: parsedResponse.urgency || 'LOW',
      };

      const response: AnalysisResponse = {
        role: request.role,
        analysis: aiResponse,
        recommendation,
        confidence: parsedResponse.confidence || 50,
        reasoning: parsedResponse.reasoning || aiResponse,
        timestamp: Date.now(),
      };

      const duration = Date.now() - startTime;
      this.logger.log(`✅ ${request.role} 分析完成: ${recommendation.action} (置信度: ${response.confidence}%, 耗时: ${duration}ms)`);
      
      return response;
    } catch (error) {
      const duration = Date.now() - startTime;
      this.logger.error(`❌ ${request.role} 分析失败 (耗时: ${duration}ms):`, {
        error: error.message,
        stack: error.stack,
        role: request.role,
      });

      // 返回一个安全的默认响应，而不是抛出错误
      const fallbackResponse: AnalysisResponse = {
        role: request.role,
        analysis: `分析失败: ${error.message}`,
        recommendation: {
          action: 'HOLD',
          urgency: 'LOW',
        },
        confidence: 0,
        reasoning: `由于技术问题，${request.role} 分析失败，建议保持当前状态`,
        timestamp: Date.now(),
      };

      this.logger.warn(`${request.role} 使用降级响应`);
      return fallbackResponse;
    }
  }

  // 多角色协同分析
  async multiRoleAnalysis(
    marketData: any,
    accountInfo: any,
    positions: any[],
    klineData: any[],
  ): Promise<AnalysisResponse[]> {
    const roles = [
      TradingRole.TECHNICAL_ANALYST,
      TradingRole.FUNDAMENTAL_ANALYST,
      TradingRole.RISK_MANAGER,
      TradingRole.NEWS_ANALYST,
    ];

    const startTime = Date.now();
    this.logger.log(`🔄 开始多角色分析 (${roles.length} 个角色)...`);

    // 使用 Promise.allSettled 而不是 Promise.all，确保即使部分分析失败也能继续
    const analysisPromises = roles.map(role =>
      this.analyzeByRole({
        marketData,
        accountInfo,
        positions,
        klineData,
        role,
      }),
    );

    try {
      const results = await Promise.allSettled(analysisPromises);
      
      const successfulAnalyses: AnalysisResponse[] = [];
      const failedAnalyses: string[] = [];

      results.forEach((result, index) => {
        if (result.status === 'fulfilled') {
          successfulAnalyses.push(result.value);
        } else {
          const role = roles[index];
          failedAnalyses.push(role);
          this.logger.error(`${role} 分析失败:`, result.reason);
          
          // 为失败的分析创建降级响应
          const fallbackResponse: AnalysisResponse = {
            role,
            analysis: `分析失败: ${result.reason?.message || '未知错误'}`,
            recommendation: {
              action: 'HOLD',
              urgency: 'LOW',
            },
            confidence: 0,
            reasoning: `由于技术问题，${role} 分析失败，建议保持当前状态`,
            timestamp: Date.now(),
          };
          successfulAnalyses.push(fallbackResponse);
        }
      });

      const duration = Date.now() - startTime;
      
      if (failedAnalyses.length > 0) {
        this.logger.warn(`⚠️ 多角色分析部分完成 (${successfulAnalyses.length - failedAnalyses.length}/${roles.length} 成功, 耗时: ${duration}ms)`);
        this.logger.warn(`失败的角色: ${failedAnalyses.join(', ')}`);
      } else {
        this.logger.log(`✅ 多角色分析完成 (${successfulAnalyses.length}/${roles.length} 成功, 耗时: ${duration}ms)`);
      }

      return successfulAnalyses;
    } catch (error) {
      const duration = Date.now() - startTime;
      this.logger.error(`❌ 多角色分析完全失败 (耗时: ${duration}ms):`, error);
      
      // 即使完全失败，也返回降级响应而不是抛出错误
      const fallbackAnalyses: AnalysisResponse[] = roles.map(role => ({
        role,
        analysis: `分析失败: ${error.message}`,
        recommendation: {
          action: 'HOLD',
          urgency: 'LOW',
        },
        confidence: 0,
        reasoning: `由于技术问题，${role} 分析失败，建议保持当前状态`,
        timestamp: Date.now(),
      }));

      this.logger.warn('使用降级分析响应');
      return fallbackAnalyses;
    }
  }

  // 生成最终决策
  async generateConsensusDecision(
    analyses: AnalysisResponse[],
    marketData: any,
    accountInfo: any,
  ): Promise<ConsensusDecision> {
    const startTime = Date.now();
    this.logger.log('🎯 交易执行官开始制定最终决策...');

    try {
      // 验证输入数据
      if (!analyses || analyses.length === 0) {
        throw new Error('没有可用的分析结果');
      }

      // 检查是否有失败的分析
      const failedAnalyses = analyses.filter(a => a.confidence === 0);
      if (failedAnalyses.length > 0) {
        this.logger.warn(`检测到 ${failedAnalyses.length} 个失败的分析:`, 
          failedAnalyses.map(a => a.role));
      }

      // 构建执行官分析请求
      const executionPrompt = this.rolePrompts.get(TradingRole.EXECUTION_OFFICER);
      if (!executionPrompt) {
        throw new Error('执行官角色提示词未找到');
      }
      
      let analysisPrompt = executionPrompt.analysisPrompt
        .replace('{technicalAnalysis}', JSON.stringify(analyses.find(a => a.role === TradingRole.TECHNICAL_ANALYST), null, 2))
        .replace('{fundamentalAnalysis}', JSON.stringify(analyses.find(a => a.role === TradingRole.FUNDAMENTAL_ANALYST), null, 2))
        .replace('{riskManagement}', JSON.stringify(analyses.find(a => a.role === TradingRole.RISK_MANAGER), null, 2))
        .replace('{newsAnalysis}', JSON.stringify(analyses.find(a => a.role === TradingRole.NEWS_ANALYST), null, 2))
        .replace('{marketData}', JSON.stringify(marketData, null, 2))
        .replace('{accountInfo}', JSON.stringify(accountInfo, null, 2));

      this.logger.debug(`执行官提示词长度: ${analysisPrompt.length} 字符`);

      const aiResponse = await this.callDeepSeekAPI(analysisPrompt, executionPrompt.systemPrompt);
      
      if (!aiResponse || aiResponse.trim().length === 0) {
        throw new Error('执行官分析返回空响应');
      }

      this.logger.debug(`执行官收到响应，长度: ${aiResponse.length} 字符`);
      
      // 解析最终决策
      let parsedResponse: any;
      try {
        const jsonMatch = aiResponse.match(/\{[\s\S]*\}/);
        if (jsonMatch) {
          parsedResponse = JSON.parse(jsonMatch[0]);
          this.logger.debug('执行官响应 JSON 解析成功');
        } else {
          throw new Error('响应中未找到JSON格式');
        }
      } catch (parseError) {
        this.logger.warn('最终决策响应解析失败，使用保守策略:', {
          error: parseError.message,
          responsePreview: aiResponse.substring(0, 200) + '...'
        });
        parsedResponse = {
          action: 'HOLD',
          confidence: 30,
          reasoning: '由于分析结果解析失败，采用保守策略',
          quantity: 0,
        };
      }

      // 验证和修正解析结果
      const validActions = ['BUY', 'SELL', 'HOLD', 'CLOSE'];
      if (!validActions.includes(parsedResponse.action)) {
        this.logger.warn(`执行官无效的 action: ${parsedResponse.action}，使用默认值 HOLD`);
        parsedResponse.action = 'HOLD';
      }

      if (typeof parsedResponse.confidence !== 'number' || parsedResponse.confidence < 0 || parsedResponse.confidence > 100) {
        this.logger.warn(`执行官无效的 confidence: ${parsedResponse.confidence}，使用默认值 50`);
        parsedResponse.confidence = 50;
      }

      // 智能计算quantity默认值
      if (typeof parsedResponse.quantity !== 'number' || parsedResponse.quantity < 0 || isNaN(parsedResponse.quantity)) {
        let defaultQuantity = 0;
        
        // 如果是买入或卖出操作，计算合理的默认数量
        if (parsedResponse.action === 'BUY' || parsedResponse.action === 'SELL') {
          try {
            // 基于可用余额计算默认数量（使用5%的保守比例）
            const availableBalance = accountInfo?.availableBalance || 0;
            const currentPrice = marketData?.currentPrice?.price || 0;
            
            if (availableBalance > 0 && currentPrice > 0) {
              const riskPercentage = 0.05; // 5%的风险比例
              const usdtAmount = availableBalance * riskPercentage;
              defaultQuantity = parseFloat((usdtAmount / currentPrice).toFixed(6));
              
              this.logger.log(`计算默认交易数量: 可用余额=${availableBalance}, 当前价格=${currentPrice}, 默认数量=${defaultQuantity}`);
            }
          } catch (error) {
            this.logger.warn('计算默认数量失败:', error.message);
          }
        }
        
        this.logger.warn(`执行官无效的 quantity: ${parsedResponse.quantity}，使用计算的默认值 ${defaultQuantity}`);
        parsedResponse.quantity = defaultQuantity;
      }

      // 计算综合置信度（基于各角色的置信度加权平均）
      const validAnalyses = analyses.filter(a => a.confidence > 0);
      
      // 定义角色权重，技术分析和基本面分析权重更高
      const roleWeights = {
        'technical_analyst': 0.3,
        'fundamental_analyst': 0.3,
        'risk_manager': 0.2,
        'news_analyst': 0.2,
      };
      
      let weightedSum = 0;
      let totalWeight = 0;
      
      validAnalyses.forEach(analysis => {
        const weight = roleWeights[analysis.role] || 0.1;
        weightedSum += analysis.confidence * weight;
        totalWeight += weight;
      });
      
      const avgConfidence = totalWeight > 0 
        ? weightedSum / totalWeight
        : 30; // 如果所有分析都失败，使用低置信度

      // 使用加权平均而不是取最小值，让决策更积极
      const executionConfidence = parsedResponse.confidence || 50;
      const finalConfidence = Math.round((avgConfidence * 0.7 + executionConfidence * 0.3));

      const decision: ConsensusDecision = {
        finalAction: parsedResponse.action || 'HOLD',
        quantity: parsedResponse.quantity || 0,
        price: parsedResponse.price,
        stopLoss: parsedResponse.stopLoss,
        takeProfit: parsedResponse.takeProfit,
        leverage: parsedResponse.leverage,
        confidence: finalConfidence,
        reasoning: parsedResponse.reasoning || aiResponse,
        participatingRoles: analyses.map(a => a.role),
        timestamp: Date.now(),
      };

      const duration = Date.now() - startTime;
      this.logger.log(`✅ 最终决策: ${decision.finalAction} (置信度: ${decision.confidence}%, 耗时: ${duration}ms)`);
      
      return decision;
    } catch (error) {
      const duration = Date.now() - startTime;
      this.logger.error(`❌ 生成最终决策失败 (耗时: ${duration}ms):`, {
        error: error.message,
        stack: error.stack,
        analysesCount: analyses?.length || 0,
      });

      // 返回一个安全的默认决策，而不是抛出错误
      const fallbackDecision: ConsensusDecision = {
        finalAction: 'HOLD',
        quantity: 0,
        confidence: 0,
        reasoning: `由于技术问题，决策生成失败: ${error.message}。为安全起见，建议保持当前状态。`,
        participatingRoles: analyses?.map(a => a.role) || [],
        timestamp: Date.now(),
      };

      this.logger.warn('使用降级决策');
      return fallbackDecision;
    }
  }
}